﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Security.Cryptography;

namespace GA.Server.Api
{
    public abstract class ApiCall
    {
        public XmlDocument XmlDocument { get; protected set; }

        public ApiCall()
        {
        }

        public ApiCall(int clientId, string authorizationCode)
        {
            ClientId = clientId;
            Signature = CreateHash(clientId, ApiCallName, authorizationCode);
        }

        protected abstract string ApiCallName { get; }
        protected int ClientId { get; private set; }
        protected string Signature { get; private set; }

        protected void LoadXmlDocument(string parameters)
        {
            XmlDocument = new XmlDocument();

            string xmlLocation = string.Empty;
            xmlLocation = string.Format("{0}{1}?clientId={2}&timestamp={3}&signature={4}", sApiCall, ApiCallName, ClientId, DateTime.Now.ToUniversalTime().ToString(sDateTimeFormat), Signature);
            if (parameters != null && parameters.Length > 0) 
            {
                xmlLocation += "&" + parameters;
            }
            Console.WriteLine("XML Location: " + xmlLocation);

            XmlDocument.Load(xmlLocation);
        }

        private const string sApiCall = "https://accounts.globalagendagame.com/GAStats/GlobalAgendaSrv.svc/";
        private const string sDateTimeFormat = "yyyy-MM-dd HH:mm:ssZ";

        private static string CreateHash(int clientId, string action, string authorizationCode)
        {
            string data = string.Concat(clientId.ToString(), action, DateTime.Now.ToUniversalTime().ToString(sDateTimeFormat)).ToLower();

            Encoding encoding = new UTF8Encoding();
            byte[] salt = encoding.GetBytes(authorizationCode);
            HMACMD5 hmac = new HMACMD5(salt);
            byte[] dataBytes = Encoding.Unicode.GetBytes(data.ToCharArray());
            byte[] computedHash = hmac.ComputeHash(dataBytes);
            string computedHashString = Convert.ToBase64String(computedHash);
            computedHashString = Convert.ToBase64String(StringToUTF8ByteArray(computedHashString));

            return computedHashString;
        }

        private static Byte[] StringToUTF8ByteArray(string array)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            byte[] byteArray = encoding.GetBytes(array);
            return byteArray;
        }
    }
}
